#include <jni.h>
#include <string>
#include <opencv2/imgproc/types_c.h>
#include "FaceTrack.h"

using namespace std;


extern "C"
JNIEXPORT jlong JNICALL
Java_com_dongnao_douyin_camera_face_FaceTrack_native_1create(JNIEnv *env, jobject instance, jstring model_,
                                                      jstring seeta_) {
    const char *model = env->GetStringUTFChars(model_, 0);
    const char *seeta = env->GetStringUTFChars(seeta_, 0);

    FaceTrack *faceTrack = new FaceTrack(model, seeta);

    env->ReleaseStringUTFChars(model_, model);
    env->ReleaseStringUTFChars(seeta_, seeta);
    return reinterpret_cast<jlong>(faceTrack);
}


extern "C"
JNIEXPORT void JNICALL
Java_com_dongnao_douyin_camera_face_FaceTrack_native_1start(JNIEnv *env, jobject instance, jlong self) {

    //在java层保存 jni 的 create 返回的FaceTrack.cpp 对象在jlong中
    //可以这native-lib.cpp中创建一个FaceTrack 实例，就不要传递出去  再传回来了
    if (self == 0) {
        return;
    }
    FaceTrack *me = (FaceTrack *) self;
    me->startTracking();

}

extern "C"
JNIEXPORT void JNICALL
Java_com_dongnao_douyin_camera_face_FaceTrack_native_1stop(JNIEnv *env, jobject instance, jlong self) {


    if (self == 0) {
        return;
    }
    FaceTrack *me = (FaceTrack *) self;
    me->stopTracking();
    delete me;
}

extern "C"
JNIEXPORT jobject JNICALL
Java_com_dongnao_douyin_camera_face_FaceTrack_native_1detector(JNIEnv *env, jobject instance, jlong self,
                                                        jbyteArray data_,jint cameraId,  jint width,
                                                        jint height) {
    if (self == 0) {
        return NULL;
    }
    jbyte *data = env->GetByteArrayElements(data_, NULL);
    FaceTrack *me = (FaceTrack *) self;
    Mat src(height + height / 2, width, CV_8UC1, data);// 彩色图像需要UV  (3/2)height 灰度图不需要 可以直接用height
    //opencv
    cvtColor(src, src, CV_YUV2RGBA_NV21);//YUV(NV21) 转RGBA
    if (cameraId == 1) {

        //前置 逆时针旋转90度
        rotate(src, src, ROTATE_90_COUNTERCLOCKWISE);
        // y 翻转 镜像
        flip(src, src, 1);
    } else {
        //后置 顺时针旋转90度
        rotate(src, src, ROTATE_90_CLOCKWISE);
    }

    cvtColor(src, src, COLOR_RGBA2GRAY);//转灰度图 降噪
    //直方图均衡化 增强对比效果
    equalizeHist(src, src);

    vector<Rect2f> rects;
    //送去定位
    me->detector(src, rects);
    env->ReleaseByteArrayElements(data_, data, 0);//使用完java传递过来的图像数组便释放掉

    int w = src.cols;//列数
    int h = src.rows;//行数
    src.release();
    int ret = rects.size();
    if (ret) {
        jclass clazz = env->FindClass("com/dongnao/douyin/camera/face/Face");
        jmethodID costruct = env->GetMethodID(clazz, "<init>", "(IIII[F)V");
        int size = ret * 2;//一个向量包含2个点 x y
        //创建java 的float 数组
        jfloatArray floatArray = env->NewFloatArray(size);
        for (int i = 0, j = 0; i < size; j++) {
            float f[2] = {rects[j].x, rects[j].y};
            env->SetFloatArrayRegion(floatArray, i, 2, f);//把f中的2个数据复制到floatArray的 i 位置上
            i += 2;//2个数据 每次下标加2
        }
        Rect2f faceRect = rects[0];//float类型的矩阵 2即to（two 同音）
        int width = faceRect.width;
        int height = faceRect.height;
        jobject face = env->NewObject(clazz, costruct, width, height, w, h,
                                      floatArray);//jni调用构建方法 创建JAVA Face 对象 ，相当于java反射
        return face;
    }
    return NULL;
}
